Semi-Automatic Porting

The Cyclone compiler includes a simple porting mode which you can use to try to move your C code closer to Cyclone. The porting tool is not perfect, but it’s a start and we hope to develop it more in the future.

When porting a file, say foo.c, you’ll first need to copy the file to foo.cyc and then edit it to add __cyclone_port_on__; and __cyclone_port_off__; around the code that you want Cyclone to port. For example, if after copying foo.c, the file foo.cyc contains the following:

1.   #include <stdio.h>
2. 
3.   void foo(char *s) {
4.     printf(s);
5.   }
6. 
7.   int main(int argc, char **argv) {
8.     argv++;
9.     for (argc--; argc >= 0; argc--, argv++)
10.      foo(*argv);
11.  }

then you’ll want to insert __cyclone_port_on__; at line 2 and __cyclone_port_off__; after line 11. You do not want to port standard include files such as stdio, hence the need for the delimiters.

Next compile the file with the -port flag:

  cyclone -port foo.cyc > rewrites.txt

and pipe the output to a file, in this case rewrites.txt. If you edit the output file, you will see that the compiler has emitted a list of edits such as the following:

  foo.cyc(5:14-5:15): insert `?' for `*'
  foo.cyc(9:24-9:25): insert `?' for `*'
  foo.cyc(9:25-9:26): insert `?' for `*'

You can apply these edits by running the rewrite program on the edits:

  rewrite -port foo.cyc > rewrites.txt

(The rewrite program is written in Cyclone and included in the tools sub-directory.) This will produce a new file called foo_new.cyc which should look like this:

#include <stdio.h>

__cyclone_port_on__;

void foo(char ?s) { 
  printf(s);
}

int main(int argc, char ??argv) {
  argv++;
  for (argc--; argc >= 0; argc--, argv++) 
    foo(*argv);
}
__cyclone_port_off__;

Notice that the porting system has changed the pointers from thin pointers to fat pointers (?) to support the pointer arithmetic that is done in main, and that this constraint has flowed to procedures that are called (e.g., foo).

You’ll need to strip out the port-on and port-off directives and then try to compile the file with the Cyclone compiler. In this case, the rewritten code in foo_new.cyc compiles with a warning that main might not return an integer value. In general, you’ll find that the porting tool doesn’t always produce valid Cyclone code. Usually, you’ll have to go in and modify the code substantially to get it to compile. Nonetheless, the porting tool can take care of lots of little details for you.